package com.itsu.app.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itsu.app.exception.MyException;
import com.itsu.app.interceptor.UserThreadLocal;
import com.itsu.commons.utils.SendSmsUtil;
import com.itsu.interfaces.entity.*;
import com.itsu.interfaces.service.SettingService;
import com.itsu.interfaces.service.UserBlackService;
import com.itsu.interfaces.service.UserLikeService;
import com.itsu.pojo.constants.Constants;
import com.itsu.pojo.enums.ResultCode;
import com.itsu.pojo.results.ErrorResult;
import com.itsu.pojo.vo.*;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class AppMyCenterService {

    @Autowired
    AppUserInfoService appUserInfoService;

    @Autowired
    AppQuestionService appQuestionService;

    @Autowired
    AppUserService appUserService;

    @Reference
    UserLikeService userLikeService;

    @Reference
    SettingService settingService;

    @Reference
    UserBlackService userBlackService;

    @Autowired
    RedisTemplate<String, String> redisTemplate;


    public UserInfoVo findUserByUid(Long userId) {
        UserInfoEntity user = appUserInfoService.findUserByUid(userId);
        UserInfoVo vo = new UserInfoVo();
        vo.setId(user.getUserId());
        vo.setAvatar(user.getLogo());
        vo.setNickname(user.getNickName());
        vo.setBirthday(user.getBirthday());
        vo.setAge(user.getAge().toString());
        vo.setGender(user.getSex() == 1 ? "woman" : "man");
        vo.setCity(user.getCity());
        vo.setEducation(user.getEdu());
        vo.setIncome(user.getIncome());
        vo.setProfession(user.getIndustry());
        vo.setMarriage("已婚".equals(user.getMarriage())? 1 : 0);
        return vo;
    }

    public CountsVo queryCounts() {
        List<UserLike> likeList = userLikeService.findLikeList(UserThreadLocal.getUid());
        List<Long> likeUserIds = CollUtil.getFieldValues(likeList, "likeUserId", Long.class);
        List<UserLike> fanList = userLikeService.findFanList(UserThreadLocal.getUid());
        Map<Long, UserLike> fanListMap = CollUtil.fieldValueMap(fanList, "userId");
        Long eachLoveCount = 0L;
        for (Long likeUserId : likeUserIds) {
            UserLike userLike = fanListMap.get(likeUserId);
            if (ObjectUtil.isNotEmpty(userLike)) {
                eachLoveCount++;
            }
        }
        CountsVo countsVo = new CountsVo();
        countsVo.setEachLoveCount(eachLoveCount);
        countsVo.setLoveCount(ObjectUtil.isEmpty(likeList) ? 0L : Convert.toLong(likeList.size()));
        countsVo.setFanCount(ObjectUtil.isEmpty(likeList) ? 0L : Convert.toLong(fanList.size()));
        return countsVo;
    }

    public void updateUserInfo(Map<String, String> map) {
        UserInfoEntity build = UserInfoEntity.builder()
                .userId(UserThreadLocal.getUid())
                .nickName(map.get("nickname"))
                .birthday(map.get("birthday"))
                .sex(ObjectUtil.isEmpty(map.get("gender")) ? null : "man".equalsIgnoreCase(map.get("gender")) ? 2 : 1)
                .city(map.get("city"))
                .edu(map.get("education"))
                .income(map.get("income"))
                .industry(map.get("profession"))
                .marriage(ObjectUtil.isEmpty(map.get("gender")) ? null : "1".equals(map.get("marriage")) ? "已婚" : "未婚")
                .build();
        appUserInfoService.updateInfo(build);
    }

    public SettingVo querySettings() {
        Long uid = UserThreadLocal.getUid();
        Question question = appQuestionService.findQuestion(Convert.toInt(uid));
        UserEntity entity = appUserService.findUserById(uid);
        Settings setting = settingService.findSettingByUid(uid);
        SettingVo settingVo = new SettingVo();
        settingVo.setId(Convert.toInt(uid));
        settingVo.setStrangerQuestion(ObjectUtil.isEmpty(question) ? null : question.getTxt());
        settingVo.setPhone(entity.getMobile());
        settingVo.setLikeNotification(setting.getLikeNotification() == 1);
        settingVo.setPinglunNotification(setting.getPinglunNotification() == 1);
        settingVo.setGonggaoNotification(setting.getGonggaoNotification() == 1);
        return settingVo;
    }

    public void updateLogo(MultipartFile headPhoto) {
        appUserInfoService.loginReginfoHead(headPhoto);
    }

    public void updateQuestions(String content) {
        appQuestionService.updateQuestions(UserThreadLocal.getUid(), content);
    }

    public PageResult getBlackList(String page, String pageSize) {
        PageResult pageResult = null;
        Page<UserBlack> blackListByUid = userBlackService.findBlackListByUid(Convert.toInt(page), Convert.toInt(pageSize), UserThreadLocal.getUid());

        List<UserBlack> records = blackListByUid.getRecords();
        if (CollUtil.isEmpty(records)) {
            pageResult = new PageResult(Convert.toInt(page), Convert.toInt(pageSize), 0L, null);
            return pageResult;
        }

        List<Long> blackUserIds = CollUtil.getFieldValues(records, "blackUserId", Long.class);

        List<UserInfoEntity> userInfoByUids = appUserInfoService.findUserByUids(blackUserIds);

        Map<Long, UserInfoEntity> userIdMap = CollUtil.fieldValueMap(userInfoByUids, "userId");
        List<UserBlackVo> vo = new ArrayList<>();
        for (UserBlack record : records) {
            UserBlackVo usersVo = new UserBlackVo();
            UserInfoEntity userInfoEntity = userIdMap.get(record.getBlackUserId());
            usersVo.setId(record.getBlackUserId());
            usersVo.setAvatar(userInfoEntity.getLogo());
            usersVo.setNickname(userInfoEntity.getNickName());
            usersVo.setGender(userInfoEntity.getSex() == 1 ? "woman" : "man");
            usersVo.setAge(userInfoEntity.getAge());
            vo.add(usersVo);
        }
        pageResult = new PageResult(Convert.toInt(page), Convert.toInt(pageSize), blackListByUid.getTotal(), vo);
        return pageResult;
    }

    public void deleteBlackUser(Long uid) {
        userBlackService.deleteByUid(uid);
    }

    public void updateSetting(Boolean like, Boolean pingLun, Boolean gongGao) {
        Settings settings = new Settings();
        settings.setUserId(UserThreadLocal.getUid());
        settings.setLikeNotification(like ? 1 : 0);
        settings.setPinglunNotification(pingLun ? 1 : 0);
        settings.setGonggaoNotification(gongGao ? 1 : 0);
        settingService.update(settings);
    }

    public void sendVerificationCode() {
//        UserEntity user = appUserService.findUserById(UserThreadLocal.getUid());

        String code = RandomUtil.randomNumbers(6);
        System.out.println(code);
//        SendSmsUtil.sendSms(user.getMobile(), code);

        redisTemplate.opsForValue().set(Constants.SMS_CODE + UserThreadLocal.getUid(), code, 5, TimeUnit.MINUTES);
    }

    public Map<String, Object> checkVerificationCode(String verificationCode) {
        String code = redisTemplate.opsForValue().get(Constants.SMS_CODE + UserThreadLocal.getUid());
        if (StrUtil.isEmpty(code)) {
            throw new MyException(new ErrorResult(ResultCode.VALIDATOR_CODE_TIMEOUT));
        }

        Map<String,Object> map = new HashMap<>();
        map.put("verification", false);
        if (verificationCode.equals(code)) {
            map.put("verification", true);
        }

        redisTemplate.delete(Constants.SMS_CODE + UserThreadLocal.getUid());

        return map;
    }

    public void updatePhone(String phone) {
        UserEntity entity = UserEntity.builder().id(UserThreadLocal.getUid()).mobile(phone).build();
        appUserService.update(entity);
    }
}
